2026-01-23
Se även Lecture 02 på Canvas som är väldigt bra!
Administrativt
Deadline att gå med i en grupp på söndag, se Canvas.
ISA
En ISA specificerar en processors beteende i termer av instruktionsuppsättning, register och minnesmodell, samt hur dessa komponenter samverkar.
Att göra en egen ISA är mycket dyrt eftersom det är extremt mycket mjukvara som behöver utvecklas för att stödja den:
- kompilatorer
- operativsystem
- libraries
- m.m.
Viktiga ISA
-
Intel/AMD x86
Endast AMD och Intel får använda
Används till: persondatorer och servrar -
ARM
Måste ha en licens för bruk
Används till: mobila enheter, embedded, Mac och vissa persondatorer och servrar -
IBM Power
Bara IBM använder nu för tiden
Används till: enterprise servrar och hpc
RISC-V
RISC-V (Reduced Instruction Set Computer 5) är en ISA (Instruction Set Architecture) som är öppet för alla att använda och används främst i embedded och mikrokontrollers.
Varianter och extentensions
RISC-V är modulärt och har tre varianter och ett flertal extensions
Varianter
-
RV32I
32 bitar
32 st 32-bitars register -
RV64I
64 bitar
32 st 64-bitars register -
RV128I
128 bitar
Används inte något (än?)
Både RV32I och RV64I har 47 maskinkodsinstruktioner.
Extensions
-
F - Single precision floating point
26 extra instruktioner
32 st 32-bitars flyttalsregister -
D - Double precision floating point
26 extra instruktioner
32 st 64-bitars flyttalsregister -
C - Compressed instructions
34 st 16-bitars intruktioner
Hälften så stora som vanliga intruktioner, vilket gör det möjligt att hämta två instruktioner samtidigt vilket drar ner hämtningar till minnet och därmed strömkonsumption. -
A - Atomiska operationer
Innehåller atomiska operationer. Det är instruktioner som läser från minnet och skriver tillbaka i en endaste operation. Används för parallellism för att undvika race-conditions. -
Sv32 - Virtuellt minne
Och fler som vi inte behöver veta.
MD307 Utvecklingskort
Det vi kommer använda i kursen. Det är av RV32I varianten, och har extensions F, C och A.
ABI
Står för Application Binary Interface.
Dokument som bestämmer konventioner för hur maskinkod på en viss ISA skall skrivas. Bestämmer bland annat t.ex:
- Var lägger man funktionsparametrar?
- Var lägger man returvärdet?
- Vem ansvarar för att spara undan register som man skriver över?
- Hur skall stacken organiseras?
Register
RISC-V har 32 st 32-bitars register. ABI har bestämda namn och syften. x0-31 är standardbenämningen på register, men när man skriver assemblerkod använder man istället ABI-namnen.

Instruktioner
RISC-V har bara 47 maskinkodsinstruktioner. MEN den har många fler assemblerkodsinstruktioner. Till exempel mv t0, t1 som kopierar värdet från t1 till t0 finns inte som en maskinkodsinstruktion. Istället återanvänder man add t0, t1, zero som mv eftersom det gör samma sak.
Assemblerinstruktioner som översätts till andra maskinkodsinstruktioner (som mv) kallas pseudoinstruktioner.
Load/Store Arkitektur
RISC-V har en Load/Store arkitektur. Det innebär att enbart Load och Store instruktioner får kommunicera med minnesbussen.
Istället för add register_0, M(register_1) som läser från minnet och adderar talen så måste man först ladda från minnet till ett register och sedan addera de register.
Varför? Det är enklare att bygga optimiserare när man vet att bara vissa instruktioner rör minnet.
Quickguide
Finns på Canvas: https://www.cse.chalmers.se/edu/resources/mop/lecture_notes/quickguide.html
Referens som innehåller register, instruktioner, periferi och allt man kan behöva man behöver. Kommer få den som en PDF några veckor innan tentan, vi kommer även få den som del av tentatesen.
I Visual Studio Code kan man köra kommandot Simple Browser: Show och öppna Quickguide i ett browserfönster.
Exempelprogram
Vi vill ha ett program som gör följande:

Med RISC-V assemblerkod skrivs det som:

Detta kompileras i sin tur till maskinkod:

Se Lecture 02 på Canvas för förklaring
Stora immediates
Instruktionerna är alltid 32-bitar så stora immediates som är t.ex. 32-bitar långa måste laddas in i flera instruktioner
Minnerymd
Vi har:
- 64 KB SRAM vilket är mycket snabbt och kan skrivas och läsas på en klockcykel
- 256 KB FLASH som är långsammare och kan bara läsas från. Har fördelen att det stannar även om strömmen försvinner
- PERIPHERAL REGISTERS som skickas vidare till bland annat GPIO, ethernet och USB. Alltså inte minnen egentligen utan är hur vi kommunicerar med resten av världen
- SCB konfigererar mikrokontrollern. Kommer inte användas i den här kursen

För våra första labbar är mikrokontrollern färdigkonfigurerad att skriva vårt program till början av SRAM. Senare i kursen kommer vi även specificera addresser utanför SRAM.
Sign extension
I följande exempel har a och b samma värde i minnet 0xFB.

Men när vi läser dessa från minnet med lb (load byte) kommer de läsas in som signed bytes, vilket innebär att de båda blir -5 i 32-bitar 0xFFFFFFFB och summan blir -10. Detta kallas sign-extension och för att fixa det i det här exemplet använder vi lbu instruktionen istället vilket läser en unsigned byte vilket fyller de övre bitsen med 0 istället för 1.
Memory Alignment
Läser ett word (4-bytes/32-bitar), detta funkar utan problem eftersom vi kan aktivera rätt 32-bitars register och läsa alla bytes från det.

Men om vi läser från en address som inte är delbar med 4 hamnar vi mellan två register. Detta är långsammare och skulle behöva utföras i flera klockcyklar, därför är detta helt förbjudet i många ISA som RISC-V.

En variabel som tar upp 4 bytes måste ligga på en address som är jämnt delbar med fyra
En variabel som tar upp 2 bytes måste ligga på en address som är jämnt delbar med två
Exempel
Säg att vi ska definiera följande variabler:
a: .byte
b: .hword
c: .hword
d: .word
Ett naivt sätt att göra det är att lägga in fler variabler för att aligna variablerna:
a: .byte
d: .byte # Dummy byte
b: .hword
c: .hword
e: .hword # Dummy hword
d: .word
Men om man skulle lägga till en byte innan måste man manuellt lägga in fler bytes vilket bara blir jobbigt. align direktivet (skrivs som .align x) säger att nästa address måste vara delbart med 2^x.
a: .byte
.align 1
b: .hword
c: .hword
.align 2
d: .word